﻿namespace 长屏滑台_一维
{
    public class Cache
    {
        private int CacheSize;
        private byte[] _Cache;
        private int InsertIndex=0;
        private Action<byte[],int,int> ParseData;  //数组，起始位置，长度
        private List<Func<byte[], int,int>> Conditions; //数组，起始位置，通过条件的数据长度，>0表示长度，否则没通过条件
        int Mode = 0;  //当缓存区满了后怎么处理，0:向前顶  1：清空数据，从头开始

        public void AddCondition(Func<byte[], int, int> Condition)
        {
            if(Conditions == null)
            {
                Conditions=new List<Func<byte[], int,int>>();
            }
            Conditions.Add(Condition);
        }

        public void AddParse(Action<byte[], int, int> Parse)
        {
            ParseData = Parse;
        }

        public Cache(int CacheSize=128)
        {
            if(CacheSize<16) CacheSize = 16;
            this.CacheSize = CacheSize;
            _Cache = new byte[CacheSize];
        }

        public void Reset(int CacheSize=128)
        {
            if (CacheSize < 16) CacheSize = 16;
            this.CacheSize = CacheSize;
            _Cache = new byte[CacheSize];
            Conditions=null;
            ParseData = null;
            Mode = 0;
            InsertIndex = 0;
        }

        public void Clear()
        {
            Array.Clear(_Cache, 0, _Cache.Length);
            InsertIndex = 0;
        }

        public void Add(byte[] Datas)
        {
            for(int i = 0; i < Datas.Length; i++)
            {
                Add(Datas[i]);
            }
        }
        public void Add(byte Data)
        {
            if(InsertIndex==CacheSize)
            {
                //缓存区已满
                //清空缓存区
                if(Mode==0)
                {
                    for (int i = 0;i<CacheSize-1;i++)
                    {
                        _Cache[i] = _Cache[i+1];
                    }
                    InsertIndex = CacheSize - 1;
                }
                if(Mode == 1)
                {
                    Array.Clear(_Cache, 0, CacheSize);
                    InsertIndex = 0;
                }
                
            }
            _Cache[InsertIndex] = Data;
            InsertIndex++;


            //查找有没有符合要求的指令
            int CmdCount = 0;
            int CmdLength = 0;
            int Index = 0;
            bool Failed = false;
            
            for (int i = 0; i < CacheSize;)
            {
                if(Conditions.Count>0)
                {
                    Failed = false;
                    foreach (var Condition in Conditions)
                    {
                        CmdLength = Condition.Invoke(_Cache, i);
                        //CmdLength表示符合要求的数据长度
                        if (CmdLength <= 0)
                        {
                            //有一个条件不满足，前进一步
                            i = i + 1;

                            Failed = true;
                            break;
                        }
                    }
                    if(Failed)
                    {
                        continue;
                    }
                    //找到了符合要求的指令，解析指令
                    ParseData.Invoke(_Cache, i, CmdLength);
                    CmdCount++;
                    i = i + CmdLength;
                    Index = i;
                }
                else
                {
                    i++;
                }
            } 

            if(CmdCount>0)
            {
                //移至开头
                if(Index==CacheSize)
                {
                    Array.Clear(_Cache, 0, CacheSize);
                    InsertIndex = 0;
                }
                else
                {
                    for (int i = 0; i < InsertIndex - Index; i++)
                    {
                        _Cache[i] = _Cache[Index + i];

                    }
                    //清空其他
                    for (int i = InsertIndex - Index; i < InsertIndex; i++)
                    {
                        _Cache[i] = 0;
                    }
                    InsertIndex = CacheSize - Index;
                }
            }
        }
    }
}
